package com.youxin.chat.pay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youxin.base.BaseResultCode;
import com.youxin.chat.basic.dto.constant.CommonConstant;
import com.youxin.chat.basic.dto.constant.SmsTypeEnum;
import com.youxin.chat.pay.convert.BankInfoConvert;
import com.youxin.chat.pay.entity.vo.*;
import com.youxin.chat.pay.mapper.BankInfoMapper;
import com.youxin.chat.pay.mapper.UserCardMapper;
import com.youxin.chat.pay.mapper.UserWalletMapper;
import com.youxin.chat.pay.model.BankInfo;
import com.youxin.chat.pay.model.ChannelAccount;
import com.youxin.chat.pay.model.UserCard;
import com.youxin.chat.pay.model.UserWallet;
import com.youxin.chat.pay.service.UserWalletService;
import com.youxin.chat.pay.service.channel.ChannelRouter;
import com.youxin.chat.pay.service.manager.UserWalletManager;
import com.youxin.chat.pay.service.rpc.SmsService;
import com.youxin.chat.pay.service.rpc.UserService;
import com.youxin.chat.user.dto.UserInfoDto;
import com.youxin.common.config.YouxinCommonProperties;
import com.youxin.dozer.DozerUtils;
import com.youxin.exception.SystemException;
import com.youxin.utils.MD5Util;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

import java.util.List;
import java.util.stream.Collectors;

import static com.youxin.common.constant.RedisKey.SMS_CODE_PREFIX;

/**
 * description: UserWalletServiceImpl <br>
 * date: 2020/3/1 10:19 <br>
 * author: llkj <br>
 * version: 1.0 <br>
 */
@Service
public class UserWalletServiceImpl extends ServiceImpl<UserWalletMapper, UserWallet> implements UserWalletService {

    @Resource
    private UserCardMapper userCardMapper;

    @Resource
    private BankInfoMapper bankInfoMapper;

    @Resource
    private DozerUtils dozerUtils;

    @Resource
    private UserService userService;

    @Resource
    private SmsService smsService;

    @Resource
    private ChannelRouter channelRouter;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private YouxinCommonProperties youxinCommonProperties;

    @Resource
    private UserWalletManager userWalletManager;

    @Override
    public UserWalletVo showUserWallet(String userNo) {
        UserWallet userWallet = this.baseMapper.selectUserWalleByUserNo(userNo);
        UserWalletVo userWalletView = new UserWalletVo();
        userWalletView.setBalance(userWallet.getUserBalance());
//        UserInfoDto userInfo = userService.getByUserNo(userNo);
        userWalletView.setHasPayPass(StringUtils.isEmpty(userWallet.getPayPwd()) ? 0 : 1);
        int count = userCardMapper.selectCount(new LambdaQueryWrapper<UserCard>().eq(UserCard::getUserNo, userNo)
                .eq(UserCard::getBindStatus, 1).eq(UserCard::getIsDeleted, 0));
        userWalletView.setHasBindCard(count > 0 ? 1 : 0);
        userWalletView.setWalletStatus(userWallet.getWalletStatus());
        return userWalletView;
    }

    @Override
    public UserBalanceVo selectBalance(String userNo) {
        UserWallet userWallet = this.baseMapper.selectUserWalleByUserNo(userNo);
        UserBalanceVo userWalletDto = dozerUtils.map(userWallet, UserBalanceVo.class);
        return userWalletDto;
    }

    @Override
    public void userpaypaw(PayPassReq payPawDto, String userNo) {
        UserWallet userWallet = this.baseMapper.selectUserWalleByUserNo(userNo);
        String salt = getSalt(userNo);
        if (payPawDto.getNewPass() == null) {
            throw new SystemException(BaseResultCode.COMMON_FAIL, "新密码为空");
        }
        String newpass = MD5Util.md5Salt(payPawDto.getNewPass().toUpperCase(), salt, 1);
        if (StringUtils.isEmpty(payPawDto.getOldPass())) {
            if (!StringUtils.isEmpty(userWallet.getPayPwd())) {
                throw new SystemException(BaseResultCode.COMMON_FAIL, "旧密码为空");
            }
            userWalletManager.updateWalletPass(userNo, newpass);
        } else {
            String oldpass = MD5Util.md5Salt(payPawDto.getOldPass().toUpperCase(), salt, 1);
            if (!StringUtils.isEmpty(userWallet.getPayPwd()) && !userWallet.getPayPwd().equalsIgnoreCase(oldpass)) {
                throw new SystemException(BaseResultCode.COMMON_FAIL, "旧密码不正确");
            }
            userWalletManager.updateWalletPass(userNo, newpass);
        }
    }

    @Override
    public void forgetPayPaw(String userNo, ForgetPayPassReq forgetPayPaw) {
        UserInfoDto userInfo = userService.getByUserNo(userNo);
        String key = SMS_CODE_PREFIX + userInfo.getMobile() + "." + SmsTypeEnum.FORGET_PAY_PASS.getType();
        if (forgetPayPaw.getCode().equalsIgnoreCase(stringRedisTemplate.opsForValue().get(key))) {
            UserWallet userWallet = this.baseMapper.selectUserWalleByUserNo(userNo);
            if (forgetPayPaw.getNewPass() == null) {
                throw new SystemException(BaseResultCode.COMMON_FAIL, "新支付密码为空");
            } else {
                String salt = getSalt(userNo);
                String newPass = MD5Util.md5Salt(forgetPayPaw.getNewPass().toUpperCase(), salt, 1);
                userWalletManager.updateWalletPass(userNo, newPass);
            }
        } else {
            throw new SystemException(BaseResultCode.SECURITY_ERROR, "验证码不正确");
        }
    }

    @Override
    public void forgetPayPawSms(String userNo, Long ip) {
        String content = "您的短信验证码为%s,该短信验证码在3分钟内有效，此验证码勿提供给他人，请勿转发";
        UserInfoDto userInfo = userService.getByUserNo(userNo);
        smsService.sendSms(SmsTypeEnum.FORGET_PAY_PASS.getType(), userInfo.getMobile(), content, ip);
    }

    @Override
    public List<BankInfoVo> listBank() {
        ChannelAccount channelAccount = channelRouter.getDefaultChannelAcccount();
        List<BankInfo> bankList = bankInfoMapper.getList(channelAccount.getChannelCode());
        List<BankInfoVo> list = bankList.stream().map(item -> BankInfoConvert.modelToDto(item, youxinCommonProperties.getDownloadUrl())).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<UserCardVo> getUserCardList(String userNo) {
        List<UserCardVo> list = userCardMapper.getUserCardList(userNo);
        list.stream().forEach(item -> {
            if (!StringUtils.isEmpty(item.getBankIcon())) {
                item.setBankIcon(youxinCommonProperties.getDownloadUrl() + item.getBankIcon());
            }
            if (!StringUtils.isEmpty(item.getBankCover())) {
                item.setBankCover(youxinCommonProperties.getDownloadUrl() + item.getBankCover());
            }
        });
        return list;
    }

    @Override
    public void updateUserWalletStates(String userNo, Integer status) {

        if (Integer.compare(CommonConstant.UserStatus.LOCK, status) != 0 && Integer.compare(CommonConstant.UserStatus.ON_LINE, status) != 0) {
            throw new SystemException(BaseResultCode.COMMON_FAIL, "用户参数不正确");
        }
        userWalletManager.updateWalletStatus(userNo, status);
    }

    @Override
    public int getWalletStatus(String userNo) {
        return userWalletManager.getWalletStatus(userNo);
    }

    private String getSalt(String userNo) {
        int endIndex = userNo.length();
        int beginIndex = 0;

        if (endIndex > 6) {
            beginIndex = endIndex - 6;
        }
        String salt = userNo.substring(beginIndex, endIndex);
        return salt;
    }
}
